using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
public class CandyDrop : MonoBehaviour
{
    public static CandyDrop instance;
    private GameManager manager;
    [SerializeField]
    private tk2dTextMesh score, MoveN;
	public GameObject special_candy;
	public GameObject bar;
	[SerializeField]
	private GameObject line_under;
    void Awake()
    {
        instance = this;
	}

    void Start()
    {
        manager = GameManager.getInstance();
    }


    public void DroppingCandy()
	{
		if(manager.gamestate!=GameState.destroy){return;}
		manager.IsMatch=false;
		Dropping();
		if(special_candy!=null){
			CancelInvoke();
			Invoke("SecondBoom",2f);

		}else if (manager.IsMatch)
        {
			DroppingCandy();
        }else if(manager.IsDestroySpecialMatch){
			return;
		}
        else
		{
			//CheckPositionObjects();
            manager.gamestate = GameState.dropping;
        }
    }
	private void SecondBoom(){
		if(special_candy==null){return;}
		manager.gamestate=GameState.destroy;
		manager.IsDestroySpecialMatch=false;
		special_candy.GetComponent<CandyController>().IsMatched=true;
		CandyMatchedConditions.instance.SpecialWithSimple(special_candy);
		special_candy=null;
		Invoke("DroppingCandy", 0.15f);	
	}
	public void Dropping()
	{
		CandyDemo.instance.Hint();
		if(Player.instance!=null){
			Player.instance.CancelInvoke();        
		}
		CheckPositionObjects();
        manager.IsMatch = false;
        for ( int j = 0; j < CandyDemo.instance.level.GetCandy().Length; j++)
        {
			if (CandyDemo.instance.level.GetCandy()[j].GetComponent<CandyController>().IsMatched)
            {
                SetCandyProperty(CandyDemo.instance.level.GetCandy()[j]);
				if (CandyDemo.instance.level.GetCandy()[j].GetComponent<CandyController>().Type != "simple")
                {
					if(SpecialCandyDestroy(CandyDemo.instance.level.GetCandy()[j])){
						manager.IsDestroySpecialMatch=true;
						continue;
					}
                }
				FallDownCandy(CandyDemo.instance.level.GetCandy()[j],j);
			}
        }
        CandyDemo.instance.suggest_item1 = CandyDemo.instance.suggest_item2 = null;
        KinematicCandy(false);
    }
	private GameObject[] tmp,tem;
	public void CheckPositionObjects(){
		tmp=null;
		tmp=CandyDemo.instance.second_board.Where(e=>e.transform.position.y<=bar.transform.position.y).ToArray();
		if(tmp.Length>0){
			for(int k=0;k<tmp.Length;k++){
				tem=CandyDemo.instance.level.GetCandy().Where(e=>e.transform.position.y>=bar.transform.position.y).ToArray();
				if(tem.Length==0){continue;}
				temp=tem[0];
				SwapObjectIn2List(CandyDemo.instance.level.GetCandy(),FindIndexObjectInList(temp,CandyDemo.instance.level.GetCandy()),
				                  CandyDemo.instance.second_board,FindIndexObjectInList(tmp[k], CandyDemo.instance.second_board));
			}
		}
		CheckCandyIsOverTheBar();
		CheckSecondBoardObjectUnderTheBar();
//		tem=CandyDemo.instance.level.GetCandy().Where(e=>e.transform.position.y<line_under.transform.position.y).ToArray();
//		if(tem.Length>0){
//			for(int i=0;i<tem.Length;i++){
//				tem[i].transform.position=new Vector3(tem[i].transform.position.x,line_under.transform.position.y+15,tem[i].transform.position.z);
//			}
//		}
//		tem=CandyDemo.instance.second_board.Where(e=>e.transform.position.y<line_under.transform.position.y).ToArray();
//		if(tem.Length>0){
//			for(int i=0;i<tem.Length;i++){
//				tem[i].transform.position=new Vector3(tem[i].transform.position.x,line_under.transform.position.y+15,tem[i].transform.position.z);
//			}
//		}
	}
	public bool CheckSecondBoardObjectUnderTheBar(){
		tmp=CandyDemo.instance.second_board.Where(e=>e.transform.position.y<=bar.transform.position.y).ToArray();
		if(tmp.Length>0){
			for(int k=0;k<tmp.Length;k++){
				tmp[k].transform.position=new Vector3(tmp[k].transform.position.x,tmp[k].transform.position.y+10,
				                                      tmp[k].transform.position.z);
			}
			return true;
		}
		return false;
	}
	public bool CheckCandyIsOverTheBar(){
		tem=CandyDemo.instance.level.GetCandy().Where(e=>e.transform.position.y>=bar.transform.position.y).ToArray();
		if(tem.Length>0){
			for(int k=0;k<tem.Length;k++){
				tem[k].GetComponent<CandyController>().enabled=true;
				tem[k].GetComponent<CandyController>().CandyHolder.GetComponent<BoxCollider2D>().isTrigger=true;
			}
			return true;
		}
		return false;
	}
	private GameObject temp;
	private void FallDownCandy( GameObject obj,int k){
	A:
			index=FindCandyToDrop(obj.GetComponent<CandyController>().XCoord);
		if(index==-1){
			goto A;
		}
		SwapObjectIn2List(CandyDemo.instance.level.GetCandy(),k,CandyDemo.instance.second_board,index);
		CreateNewCandy(index);
		CandyDemo.instance.level.GetCandy()[k].GetComponent<CandyController>().CandyHolder.GetComponent<BoxCollider2D>().isTrigger=true;
	}
	int index;
	private int FindCandyToDrop(int pos){
		index=-1;
		temp=CandyDemo.instance.second_board.Where(e=>e.GetComponent<CandyController>().XCoord==pos).OrderBy(e=>e.GetComponent<CandyController>().YCoord).ToArray()[0];
		index=FindIndexObjectInList(temp,CandyDemo.instance.second_board);
		return index;
	}
	private void SwapObjectIn2List(GameObject[] lst,int ind,GameObject[] other_list,int other_ind){
		GameObject t=lst[ind];
		lst[ind]=other_list[other_ind];
		other_list[other_ind]=t;
		temp=null;
	}
	private int FindIndexObjectInList(GameObject obj, GameObject[] lst){
		for(int i=0;i<lst.Length;i++){
			if(lst[i]==obj){
				return i;
			}
		}
		return -1;
	}
    private void SetCandyProperty(GameObject obj)
    {
		obj.GetComponent<CandyController>().IsMatched = false;
		obj.GetComponent<CandyController>().check = false;
    }
    private bool SpecialCandyDestroy(GameObject obj)
	{
		CancelInvoke();
		CandyCheckMatch.instance.CancelInvoke();
		switch (obj.GetComponent<CandyController>().Type)
        {
            case "vertical":
			CandyEffect.instance.CreateEffect(obj, obj.GetComponent<CandyController>().Type);
                Match.instance.CreateSlideCandy(obj, "vertical");
                break;
            case "horizontal":
			CandyEffect.instance.CreateEffect(obj, obj.GetComponent<CandyController>().Type);
                Match.instance.CreateSlideCandy(obj, "horizontal");
                break;
            case "special":
			special_candy=obj;
			manager.gamestate=GameState.destroy;
            CandyMatchedConditions.instance.SpecialWithSimple(obj);
			Match.instance.ChangeType(special_candy,"simple");
			manager.IsDestroySpecialMatch=true;
			iTween.ScaleTo(special_candy.GetComponent<CandyController>().CandyObject, iTween.Hash("x", 2.5f, "y", 2.5f,"time",0.5f, "loopType", "pingpong"));
			special_candy.GetComponent<CandyController>().IsMatched=false;
			return true;
        
            case "star":
                Match.instance.AttachWithStar(obj);
                break;
        }
		return false;
    }
	public void CreateNewCandy(int ind){
		CandyDemo.instance.second_board[ind].GetComponent<CandyController>().Type="simple";
		CandyDemo.instance.second_board[ind].GetComponent<CandyController>().CreateCandy();
		CandyDemo.instance.second_board[ind].transform.position=new Vector3(CandyDemo.instance.second_board[ind].transform.position.x,
		                                                                    CandyDemo.instance.second_board[ind].transform.position.y+15	,
		                                                                    CandyDemo.instance.second_board[ind].transform.position.z);
		CandyDemo.instance.second_board[ind].GetComponent<CandyController>().ClearNeighbor();
		CandyDemo.instance.second_board[ind].GetComponent<CandyController>().enabled=false;
	}
    public void KinematicCandy(bool active)
    {
        foreach (GameObject c in CandyDemo.instance.level.GetCandy())
        {
            c.GetComponent<Rigidbody2D>().isKinematic = active;
        }
    }
}
